import { Context } from 'koa';
import { AppContext } from '@/types';
import { validate, commonSchemas } from '@/utils/validator';
import { paginated } from '@/utils/response';
import logger from '@/utils/logger';
import Joi from 'joi';
import AuditLog from '@/models/AuditLog.model';
import User from '@/models/User.model';
import { Op } from 'sequelize';

interface ListAuditLogsFilter {
  page?: number;
  pageSize?: number;
  action?: string;
  userId?: string;
  startDate?: string;
  endDate?: string;
}

/**
 * 审计日志控制器
 */
class AuditLogController {
  /**
   * 获取审计日志列表
   */
  async list(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { user } = appCtx.state;

    const schema = Joi.object({
      page: commonSchemas.page,
      pageSize: commonSchemas.pageSize,
      action: Joi.string().optional().allow(''),
      userId: Joi.string().uuid().optional(),
      startDate: Joi.date().iso().optional(),
      endDate: Joi.date().iso().optional(),
    });

    const filter = await validate<ListAuditLogsFilter>(ctx.query as any, schema);
    const page = filter.page || 1;
    const pageSize = filter.pageSize || 20;

    try {
      const where: any = {
        tenantId: user!.tenantId,
      };

      if (filter.action) {
        where.action = filter.action;
      }

      if (filter.userId) {
        where.userId = filter.userId;
      }

      if (filter.startDate || filter.endDate) {
        where.createdAt = {};
        if (filter.startDate) {
          where.createdAt[Op.gte] = new Date(filter.startDate);
        }
        if (filter.endDate) {
          where.createdAt[Op.lte] = new Date(filter.endDate);
        }
      }

      const { rows: logs, count: total } = await AuditLog.findAndCountAll({
        where,
        limit: pageSize,
        offset: (page - 1) * pageSize,
        order: [['createdAt', 'DESC']],
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'firstName', 'lastName', 'email'],
            required: false,
          },
        ],
      });

      paginated(ctx, logs, total, page, pageSize);
    } catch (error) {
      logger.error('获取审计日志失败:', error);
      ctx.throw(500, '获取审计日志失败');
    }
  }

  /**
   * 获取审计日志详情
   */
  async detail(ctx: Context) {
    const { id } = ctx.params;

    try {
      const log = await AuditLog.findByPk(id, {
        include: [
          {
            model: User,
            as: 'user',
            attributes: ['id', 'firstName', 'lastName', 'email'],
            required: false,
          },
        ],
      });

      if (!log) {
        ctx.throw(404, '审计日志不存在');
      }

      ctx.body = {
        success: true,
        data: log,
      };
    } catch (error) {
      logger.error('获取审计日志详情失败:', error);
      ctx.throw(500, '获取审计日志详情失败');
    }
  }

  /**
   * 获取操作统计
   */
  async stats(ctx: Context) {
    const appCtx = ctx as AppContext;
    const { user } = appCtx.state;

    try {
      const logs = await AuditLog.findAll({
        where: { tenantId: user!.tenantId },
        attributes: [
          'action',
          [AuditLog.sequelize!.fn('COUNT', AuditLog.sequelize!.col('id')), 'count'],
        ],
        group: ['action'],
      });

      const stats = logs.map((log: any) => ({
        action: log.action,
        count: parseInt(log.dataValues.count, 10),
      }));

      ctx.body = {
        success: true,
        data: stats,
      };
    } catch (error) {
      logger.error('获取操作统计失败:', error);
      ctx.throw(500, '获取操作统计失败');
    }
  }
}

export default new AuditLogController();

